<!DOCTYPE html>
<html lang="en">

<head>
  <title>three.js webgl - geometry - cube</title>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
  <link type="text/css" rel="stylesheet" href="http://127.0.0.1:5502/main.css" />
  <style>
    html,
    body {
      margin: 0;
      height: 100%;
    }

    #c {
      width: 100%;
      height: 100%;
      display: block;
    }
  </style>
</head>

<body>
  <canvas id="c"></canvas>


  <script type="importmap">{
      "imports": {
        "three": "https://threejs.org/build/three.module.js",
        "three/addons/": "https://threejs.org/examples/jsm/"
      }
    }</script>

  <script type="module">
    import * as THREE from 'three';
    import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    import { GUI } from 'three/addons/libs/lil-gui.module.min.js';

    function main() {

      const canvas = document.querySelector('#c');
      const renderer = new THREE.WebGLRenderer({ antialias: true, canvas });

      const fov = 45;
      const aspect = 2; // the canvas default
      const near = 0.1;
      const far = 100;
      const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
      camera.position.set(0, 10, 20);

      const controls = new OrbitControls(camera, canvas);
      controls.target.set(0, 5, 0);
      controls.update();

      const scene = new THREE.Scene();
      scene.background = new THREE.Color('black');

      {

        const planeSize = 40;

        const loader = new THREE.TextureLoader();
        const texture = loader.load('https://threejs.org/manual/examples/resources/images/checker.png');
        texture.wrapS = THREE.RepeatWrapping;
        texture.wrapT = THREE.RepeatWrapping;
        texture.magFilter = THREE.NearestFilter;
        texture.colorSpace = THREE.SRGBColorSpace;
        const repeats = planeSize / 2;
        texture.repeat.set(repeats, repeats);

        const planeGeo = new THREE.PlaneGeometry(planeSize, planeSize);
        const planeMat = new THREE.MeshPhongMaterial({
          map: texture,
          side: THREE.DoubleSide,
        });
        const mesh = new THREE.Mesh(planeGeo, planeMat);
        mesh.rotation.x = Math.PI * - .5;
        scene.add(mesh);

      }

      {

        const cubeSize = 4;
        const cubeGeo = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
        const cubeMat = new THREE.MeshPhongMaterial({ color: '#8AC' });
        const mesh = new THREE.Mesh(cubeGeo, cubeMat);
        mesh.position.set(cubeSize + 1, cubeSize / 2, 0);
        scene.add(mesh);

      }

      {

        const sphereRadius = 3;
        const sphereWidthDivisions = 32;
        const sphereHeightDivisions = 16;
        const sphereGeo = new THREE.SphereGeometry(sphereRadius, sphereWidthDivisions, sphereHeightDivisions);
        const sphereMat = new THREE.MeshPhongMaterial({ color: '#CA8' });
        const mesh = new THREE.Mesh(sphereGeo, sphereMat);
        mesh.position.set(- sphereRadius - 1, sphereRadius + 2, 0);
        scene.add(mesh);

      }

      class ColorGUIHelper {

        constructor(object, prop) {

          this.object = object;
          this.prop = prop;

        }
        get value() {

          return `#${this.object[this.prop].getHexString()}`;

        }
        set value(hexString) {

          this.object[this.prop].set(hexString);

        }

      }

      {

        const color = 0xFFFFFF;
        const intensity = 1;
        const light = new THREE.AmbientLight(color, intensity);
        scene.add(light);

        const gui = new GUI();
        gui.addColor(new ColorGUIHelper(light, 'color'), 'value').name('color');
        gui.add(light, 'intensity', 0, 5, 0.01);

      }

      function resizeRendererToDisplaySize(renderer) {

        const canvas = renderer.domElement;
        const width = canvas.clientWidth;
        const height = canvas.clientHeight;
        const needResize = canvas.width !== width || canvas.height !== height;
        if (needResize) {

          renderer.setSize(width, height, false);

        }

        return needResize;

      }

      function render() {

        if (resizeRendererToDisplaySize(renderer)) {

          const canvas = renderer.domElement;
          camera.aspect = canvas.clientWidth / canvas.clientHeight;
          camera.updateProjectionMatrix();

        }

        renderer.render(scene, camera);

        requestAnimationFrame(render);

      }

      requestAnimationFrame(render);

    }

    main();

  </script>
</body>

</html>